package com.echo.service.impl;

import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.echo.AiManager.AiManager;
import com.echo.context.WisUserIdContext;
import com.echo.entity.*;
import com.echo.enumeration.QuestionEnum;
import com.echo.mapper.*;
import com.echo.service.IExamService;
import com.echo.vo.*;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

import static com.echo.constant.AIRole.*;

/**
 * <p>
 * 考试的详细信息表 服务实现类
 * </p>
 *
 * @author echo
 * @since 2024-10-31
 */
@Service
public class ExamServiceImpl extends ServiceImpl<ExamMapper, Exam> implements IExamService {
    @Autowired
    private ExamMapper examMapper;
    @Autowired
    private QuestionMapper questionMapper;
    @Autowired
    private WisUserMapper wisuserMapper;
    @Autowired
    private QuestionLevelMapper questionLevelMapper;
    @Autowired
    private QuestionTypeMapper questionTypeMapper;
    @Autowired
    private QuestionCategoryMapper questionCategoryMapper;
    @Autowired
    private QuestionOptionMapper questionOptionMapper;
    @Autowired
    private ExamRecordMapper examRecordMapper;
    @Autowired
    private AiManager aiManager;
    @Autowired
    private ExamAnalysisMapper examAnalysisMapper;

    @Override
    public List<QuestionVo> getQuestionAll() {
        Wrapper<Question> wrapper = new QueryWrapper<Question>().lambda()
                .orderByDesc(Question::getCreateTime);
        List<Question> questionList = questionMapper.selectList(wrapper);

        return getQuestionVos(questionList);
    }


    private List<QuestionVo> getQuestionVos(List<Question> questionList) {
        // 需要自定义的question列表
        List<QuestionVo> questionVoList = new ArrayList<>();
        // 循环完成每个属性的定制
        for (Question question : questionList) {
            QuestionVo questionVo = getQuestionVo(question);
            questionVoList.add(questionVo);
        }
        return questionVoList;
    }

    public static void main(String[] args) {
        System.out.println();
    }
    private QuestionVo getQuestionVo(Question question) {
        QuestionVo questionVo = new QuestionVo();
        // 先复制能复制的属性
        BeanUtils.copyProperties(question, questionVo);
        // 设置问题的创建者
        questionVo.setQuestionCreator(
                Objects.requireNonNull(
                        wisuserMapper.selectById(
                                question.getQuestionCreatorId()
                        )
                ).getUserUsername());

        // 设置问题的难度
        questionVo.setQuestionLevel(
                Objects.requireNonNull(
                        questionLevelMapper.selectById(
                                question.getQuestionLevelId()
                        )
                ).getQuestionLevelDescription());

        // 设置题目的类别，比如单选、多选、判断等
        questionVo.setQuestionType(
                Objects.requireNonNull(
                        questionTypeMapper.selectById(
                                question.getQuestionTypeId()
                        )
                ).getQuestionTypeDescription());

        // 设置题目分类，比如数学、语文、英语、生活、人文等
        questionVo.setQuestionCategory(
                Objects.requireNonNull(
                        questionCategoryMapper.selectById(
                                question.getQuestionCategoryId()
                        )
                ).getQuestionCategoryName()
        );

        // 选项的自定义Vo列表
        List<QuestionOptionVo> optionVoList = new ArrayList<>();

        // 获得所有的选项列表

        //得到ids
        List<String> list = Arrays.asList(question.getQuestionOptionIds().split("-"));

        // 2. 创建QueryWrapper，并添加查询条件
        QueryWrapper<QuestionOption> wrapper = new QueryWrapper<>();
        wrapper.lambda()
                .in(QuestionOption::getQuestionOptionId, list); // 假设QuestionOption表的ID字段名为option_id

        // 3. 执行查询
        List<QuestionOption> optionList = questionOptionMapper.selectList(wrapper);

        // 获取所有的答案列表optionList中每个option的isAnswer选项
        List<QuestionOption> answerList = questionOptionMapper.selectBatchIds(
                Arrays.asList(question.getQuestionAnswerOptionIds().split("-"))
        );

        // 根据选项和答案的id相同设置optionVo的isAnswer属性
        for (QuestionOption option : optionList) {
            QuestionOptionVo optionVo = new QuestionOptionVo();
            BeanUtils.copyProperties(option, optionVo);
            for (QuestionOption answer : answerList) {
                if (option.getQuestionOptionId().equals(answer.getQuestionOptionId())) {
                    optionVo.setAnswer(true);
                }
            }
            optionVoList.add(optionVo);
        }

        // 设置题目的所有选项
        questionVo.setQuestionOptionVoList(optionVoList);
        return questionVo;
    }

    @Override
    public QuestionVo updateQuestion(QuestionVo questionVo) {
        // 1.把需要的属性都设置好
        StringBuilder questionAnswerOptionIds = new StringBuilder();
        List<QuestionOption> questionOptionList = new ArrayList<>();
        List<QuestionOptionVo> questionOptionVoList = questionVo.getQuestionOptionVoList();
        int size = questionOptionVoList.size();
        for (int i = 0; i < questionOptionVoList.size(); i++) {
            QuestionOptionVo questionOptionVo = questionOptionVoList.get(i);
            QuestionOption questionOption = new QuestionOption();
            BeanUtils.copyProperties(questionOptionVo, questionOption);
            questionOptionList.add(questionOption);
            if (questionOptionVo.getAnswer()) {
                if (i != size - 1) {
                    // 把更新后的答案的id加上去,记得用-连到一起
                    questionAnswerOptionIds.append(questionOptionVo.getQuestionOptionId()).append("-");
                } else {
                    // 最后一个不需要用-连接
                    questionAnswerOptionIds.append(questionOptionVo.getQuestionOptionId());
                }
            }
        }

        // 1.更新问题
        Question question = questionMapper.selectById(questionVo.getQuestionId());
        assert question != null;
        BeanUtils.copyProperties(questionVo, question);
        question.setQuestionAnswerOptionIds(questionAnswerOptionIds.toString());
        questionMapper.updateById(question);

        // 2.更新所有的option
        for (QuestionOption questionOption : questionOptionList) {
            questionOptionMapper.updateById(questionOption);
        }


        // 返回更新后的问题，方便前端局部刷新
        return getQuestionVo(question);
    }

    @Override
    public String questionCreate(QuestionCreateVo questionCreateVo) {
// 问题创建
        Question question = new Question();
        // 把能复制的属性都复制过来
        BeanUtils.copyProperties(questionCreateVo, question);
        // 设置下questionOptionIds和questionAnswerOptionIds，需要自己用Hutool生成下
        List<QuestionOption> questionOptionList = new ArrayList<>();
        List<QuestionOptionCreateVo> questionOptionCreateVoList = questionCreateVo.getQuestionOptionCreateVoList();
        for (QuestionOptionCreateVo questionOptionCreateVo : questionOptionCreateVoList) {
            QuestionOption questionOption = new QuestionOption();
            // 设置选项的的内容
            questionOption.setQuestionOptionContent(questionOptionCreateVo.getQuestionOptionContent());
            // 设置选项的id
            questionOption.setQuestionOptionId(IdUtil.simpleUUID());
            questionOptionList.add(questionOption);
        }
        // 把选项都存起来，然后才能用于下面设置Question的questionOptionIds和questionAnswerOptionIds
        for (QuestionOption questionOption : questionOptionList) {
            questionOptionMapper.insert(questionOption);
        }
        String questionOptionIds = "";
        String questionAnswerOptionIds = "";
        // 经过上面的saveAll方法，所有的option的主键id都已经持久化了
        for (int i = 0; i < questionOptionCreateVoList.size(); i++) {
            // 获取指定选项
            QuestionOptionCreateVo questionOptionCreateVo = questionOptionCreateVoList.get(i);
            // 获取保存后的指定对象
            QuestionOption questionOption = questionOptionList.get(i);
            questionOptionIds += questionOption.getQuestionOptionId() + "-";
            if (questionOptionCreateVo.getAnswer()) {
                // 如果是答案的话
                questionAnswerOptionIds += questionOption.getQuestionOptionId() + "-";
            }
        }
        // 把字符串最后面的"-"给去掉
        questionAnswerOptionIds = replaceLastSeparator(questionAnswerOptionIds);
        questionOptionIds = replaceLastSeparator(questionOptionIds);
        // 设置选项id组成的字符串
        question.setQuestionOptionIds(questionOptionIds);
        // 设置答案选项id组成的字符串
        question.setQuestionAnswerOptionIds(questionAnswerOptionIds);
        // 自己生成问题的id
        String questionId = IdUtil.simpleUUID();
        question.setQuestionId(questionId);
        // 先把创建时间和更新时间每次都取当前时间吧
        question.setCreateTime(new Date());
        question.setUpdateTime(new Date());
        // 保存问题到数据库
        questionMapper.insert(question);
        return questionId;

    }

    @Override
    public QuestionSelectionVo getSelections() {
        QuestionSelectionVo questionSelectionVo = new QuestionSelectionVo();
        //获取题目分类表
        questionSelectionVo.setQuestionCategoryList(questionCategoryMapper.selectList(null));
        //获取题目水平表
        questionSelectionVo.setQuestionLevelList(questionLevelMapper.selectList(null));
        //获取问题类型表
        questionSelectionVo.setQuestionTypeList(questionTypeMapper.selectList(null));

        return questionSelectionVo;
    }

    @Override
    public QuestionDetailVo getQuestionDetail(String id) {
        Question question = questionMapper.selectById(id);
        QuestionDetailVo questionDetailVo = new QuestionDetailVo();
        questionDetailVo.setId(id);
        questionDetailVo.setName(question.getQuestionName());
        questionDetailVo.setDescription(question.getQuestionDescription());
        // 问题类型，单选题/多选题/判断题
        questionDetailVo.setType(
                Objects.requireNonNull(
                        questionTypeMapper.selectById(
                                question.getQuestionTypeId()
                        )
                ).getQuestionTypeDescription()
        );
        // 获取当前问题的选项
        String optionIdsStr = trimMiddleLine(question.getQuestionOptionIds());
        String[] optionIds = optionIdsStr.split("-");
        // 获取选项列表
        List<QuestionOption> optionList = questionOptionMapper.selectBatchIds(Arrays.asList(optionIds));
        questionDetailVo.setOptions(optionList);
        return questionDetailVo;
    }

    @Override
    public List<ExamVo> getExamAll() {
        QueryWrapper<Exam> wrapper=new QueryWrapper<>();
        wrapper
                .lambda()
                .orderByDesc(Exam::getCreateTime);
        List<Exam> examList = examMapper.selectList(wrapper);
        return getExamVos(examList);
    }

    @Override
    public ExamQuestionTypeVo getExamQuestionType() {
        ExamQuestionTypeVo examQuestionTypeVo = new ExamQuestionTypeVo();
        // 获取所有单选题列表，并赋值到ExamVo的属性ExamQuestionSelectVoRadioList上
        List<ExamQuestionSelectVo> radioQuestionVoList = new ArrayList<>();
        QueryWrapper<Question> wrapperRADTO = new QueryWrapper<>();
        wrapperRADTO.lambda().eq(Question::getQuestionTypeId, QuestionEnum.RADIO.getId());
        List<Question> radioQuestionList = questionMapper.selectList(wrapperRADTO);
        for (Question question : radioQuestionList) {
            ExamQuestionSelectVo radioQuestionVo = new ExamQuestionSelectVo();
            BeanUtils.copyProperties(question, radioQuestionVo);
            radioQuestionVoList.add(radioQuestionVo);
        }
        examQuestionTypeVo.setExamQuestionSelectVoRadioList(radioQuestionVoList);

        // 获取所有多选题列表，并赋值到ExamVo的属性ExamQuestionSelectVoCheckList上
        List<ExamQuestionSelectVo> checkQuestionVoList = new ArrayList<>();
        QueryWrapper<Question> wrapperCHECK = new QueryWrapper<>();
        wrapperCHECK.lambda().eq(Question::getQuestionTypeId, QuestionEnum.CHECK.getId());
        List<Question> checkQuestionList = questionMapper.selectList(wrapperCHECK);
        for (Question question : checkQuestionList) {
            ExamQuestionSelectVo checkQuestionVo = new ExamQuestionSelectVo();
            BeanUtils.copyProperties(question, checkQuestionVo);
            checkQuestionVoList.add(checkQuestionVo);
        }
        examQuestionTypeVo.setExamQuestionSelectVoCheckList(checkQuestionVoList);

        // 获取所有多选题列表，并赋值到ExamVo的属性ExamQuestionSelectVoJudgeList上
        List<ExamQuestionSelectVo> judgeQuestionVoList = new ArrayList<>();
        QueryWrapper<Question> wrapperJUDGE = new QueryWrapper<>();
        wrapperJUDGE.lambda().eq(Question::getQuestionTypeId, QuestionEnum.JUDGE.getId());
        List<Question> judgeQuestionList = questionMapper.selectList(wrapperJUDGE);
        for (Question question : judgeQuestionList) {
            ExamQuestionSelectVo judgeQuestionVo = new ExamQuestionSelectVo();
            BeanUtils.copyProperties(question, judgeQuestionVo);
            judgeQuestionVoList.add(judgeQuestionVo);
        }
        examQuestionTypeVo.setExamQuestionSelectVoJudgeList(judgeQuestionVoList);
        return examQuestionTypeVo;
    }

    @Override
    public Exam create(ExamCreateVo examCreateVo, String userId) {
        // 在线考试系统创建
        Exam exam = new Exam();
        BeanUtils.copyProperties(examCreateVo, exam);
        System.out.println("ifai"+examCreateVo.getExamIfAi());
        exam.setExamId(IdUtil.simpleUUID());
        exam.setExamCreatorId(userId);
        exam.setCreateTime(new Date());
        Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.DAY_OF_MONTH, 3); // 当前日期加3天
        exam.setExamEndDate(calendar.getTime());
        exam.setUpdateTime(new Date());
        // Todo:这两个日志后面是要在前端传入的，这里暂时定为当前日期
        exam.setExamStartDate(new Date());
        // 获取当前日期
        Date currentDate = new Date();

        // 使用 Calendar 来加 2 天
        calendar.setTime(currentDate);
        calendar.add(Calendar.DATE, 2);  // 增加2天

        // 获取加了2天后的日期
        Date newDate = calendar.getTime();

        // 设置为 exam 的结束日期
        exam.setExamEndDate(newDate);
        String radioIdsStr = "";
        String checkIdsStr = "";
        String judgeIdsStr = "";
        List<ExamQuestionSelectVo> radios = examCreateVo.getRadios();
        List<ExamQuestionSelectVo> checks = examCreateVo.getChecks();
        List<ExamQuestionSelectVo> judges = examCreateVo.getJudges();
        // 得到question的id 方便去获得类型
        String questionIdToType=null;
        //这里的话其实就是去拼接id和计算总数
        int radioCnt = 0, checkCnt = 0, judgeCnt = 0;
        for (ExamQuestionSelectVo radio : radios) {
            if (radio.getChecked()) {
                questionIdToType = radio.getQuestionId();
                radioIdsStr += radio.getQuestionId() + "-";
                radioCnt++;
            }
        }
        radioIdsStr = replaceLastSeparator(radioIdsStr);
        for (ExamQuestionSelectVo check : checks) {
            if (check.getChecked()) {
                checkIdsStr += check.getQuestionId() + "-";
                checkCnt++;
            }
        }
        checkIdsStr = replaceLastSeparator(checkIdsStr);
        for (ExamQuestionSelectVo judge : judges) {
            if (judge.getChecked()) {
                judgeIdsStr += judge.getQuestionId() + "-";
                judgeCnt++;
            }
        }
        judgeIdsStr = replaceLastSeparator(judgeIdsStr);
        exam.setExamQuestionIds(radioIdsStr + "-" + checkIdsStr + "-" + judgeIdsStr);
        // 设置各个题目的id
        exam.setExamQuestionIdsRadio(radioIdsStr);
        exam.setExamQuestionIdsCheck(checkIdsStr);
        exam.setExamQuestionIdsJudge(judgeIdsStr);
        exam.setExamAvatar(examCreateVo.getExamAvatar());
        //从questionIdToType中得到对应的type填入
        Question question = questionMapper.selectById(questionIdToType);
        Integer questionCategoryId = question.getQuestionCategoryId();
        String questionCategoryName = questionCategoryMapper.selectById(questionCategoryId).getQuestionCategoryName();
        // 便于让ai生成的 因为ai生成的已经有类型了 这里
        String examType = exam.getExamType() == null ? questionCategoryName : exam.getExamType();
        exam.setExamType(examType);
        // 计算总分数
        int examScore = radioCnt * exam.getExamScoreRadio() + checkCnt * exam.getExamScoreCheck() + judgeCnt * exam.getExamScoreJudge();
        exam.setExamScore(examScore);
        examMapper.insert(exam);
        System.out.println("创建的试卷id是"+exam.getExamId());
        return exam;
    }

    @Override
    public Exam update(ExamVo examVo, String userId) {
        Exam exam = new Exam();
        BeanUtils.copyProperties(examVo, exam);
        exam.setExamCreatorId(userId); // 考试的更新人为最新的创建人
        exam.setUpdateTime(new Date()); // 考试的更新日期要记录下

        String radioIdsStr = "";
        String checkIdsStr = "";
        String judgeIdsStr = "";
        List<ExamQuestionSelectVo> radios = examVo.getExamQuestionSelectVoRadioList();
        List<ExamQuestionSelectVo> checks = examVo.getExamQuestionSelectVoCheckList();
        List<ExamQuestionSelectVo> judges = examVo.getExamQuestionSelectVoJudgeList();
        int radioCnt = 0, checkCnt = 0, judgeCnt = 0;
        for (ExamQuestionSelectVo radio : radios) {
            if (radio.getChecked()) {
                radioIdsStr += radio.getQuestionId() + "-";
                radioCnt++;
            }
        }
        radioIdsStr = replaceLastSeparator(radioIdsStr);
        for (ExamQuestionSelectVo check : checks) {
            if (check.getChecked()) {
                checkIdsStr += check.getQuestionId() + "-";
                checkCnt++;
            }
        }
        checkIdsStr = replaceLastSeparator(checkIdsStr);
        for (ExamQuestionSelectVo judge : judges) {
            if (judge.getChecked()) {
                judgeIdsStr += judge.getQuestionId() + "-";
                judgeCnt++;
            }
        }
        judgeIdsStr = replaceLastSeparator(judgeIdsStr);
        exam.setExamQuestionIds(radioIdsStr + "-" + checkIdsStr + "-" + judgeIdsStr);
        // 设置各个题目的id
        exam.setExamQuestionIdsRadio(radioIdsStr);
        exam.setExamQuestionIdsCheck(checkIdsStr);
        exam.setExamQuestionIdsJudge(judgeIdsStr);

        // 计算总分数
        int examScore = radioCnt * exam.getExamScoreRadio() + checkCnt * exam.getExamScoreCheck() + judgeCnt * exam.getExamScoreJudge();
        exam.setExamScore(examScore);
        //todo:这里可能会出问题，原是save，但是不知道是更新/插入，所以这里进行判断
        if (exam.getExamId() != null) {
            examMapper.updateById(exam);
        } else {
            examMapper.insert(exam);
        }

        return exam;
    }

    @Override
    public List<ExamCardVo> getExamCardList(String type,Boolean ifAi) {
        List<Exam> examList;
        QueryWrapper<Exam> wrapper = new QueryWrapper<>();
        System.out.println(ifAi.equals(true));
        System.out.println("type"+type);

        System.out.println(type.equals("null"));
        System.out.println(""+type == null);

        if (type.equals("null") ||type.equals(null)) {
            //如果是ai的话，
            if(ifAi.equals(true)){
                wrapper.lambda()
                        .eq(Exam::getExamIfAi,ifAi)
                        .orderByDesc(Exam::getCreateTime);
                examList = examMapper.selectList(wrapper);
            }else {
                wrapper.lambda()
                        .orderByDesc(Exam::getCreateTime);
                //这里则查询全部
                examList = examMapper.selectList(wrapper);
            }
        } else{
            //这里则为查查询分类
                wrapper.lambda()
                        .eq(Exam::getExamIfAi,ifAi)
                        .eq(Exam::getExamType,type)
                        .orderByDesc(Exam::getCreateTime);
                examList = examMapper.selectList(wrapper);
        }
        List<ExamCardVo> examCardVoList = new ArrayList<>();
        for (Exam exam : examList) {
            ExamCardVo examCardVo = new ExamCardVo();
            BeanUtils.copyProperties(exam, examCardVo);
            examCardVoList.add(examCardVo);
        }
        return examCardVoList;
    }

    @Override
    public ExamDetailVo getExamDetail(String id) {
        Exam exam = examMapper.selectById(id);
        ExamDetailVo examDetailVo = new ExamDetailVo();
        examDetailVo.setExam(exam);
        assert exam != null;
        examDetailVo.setRadioIds(exam.getExamQuestionIdsRadio().split("-"));
        examDetailVo.setCheckIds(exam.getExamQuestionIdsCheck().split("-"));
        examDetailVo.setJudgeIds(exam.getExamQuestionIdsJudge().split("-"));
        return examDetailVo;
    }
    //todo:1.判断题目+分析题目
    @Override
    public ExamRecordAnalysisVo judge(String userId, String examId, HashMap<String, List<String>> answersMap) throws JsonProcessingException {
        // todo:这里是判断分数，后面可以修改逻辑+ai分析塞在这里
        // 开始考试判分啦~~~
        // 1.首先获取考试对象和选项数组
        ExamDetailVo examDetailVo = getExamDetail(examId);
        Exam exam = examDetailVo.getExam();
        // 2.然后获取该考试下所有的题目信息
        List<String> questionIds = new ArrayList<>();
        // 2.1 题目id的数组
        List<String> radioIdList = Arrays.asList(examDetailVo.getRadioIds());
        List<String> checkIdList = Arrays.asList(examDetailVo.getCheckIds());
        List<String> judgeIdList = Arrays.asList(examDetailVo.getJudgeIds());
        questionIds.addAll(radioIdList);
        questionIds.addAll(checkIdList);
        questionIds.addAll(judgeIdList);
        // 2.2 每种题目的分数
        int radioScore = exam.getExamScoreRadio();
        int checkScore = exam.getExamScoreCheck();
        int judgeScore = exam.getExamScoreJudge();
        // 2.3 根据问题id的数组拿到所有的问题对象，供下面步骤用
        List<Question> questionList = questionMapper.selectBatchIds(questionIds);
        Map<String, Question> questionMap = new HashMap<>();
        for (Question question : questionList) {
            questionMap.put(question.getQuestionId(), question);
        }
        // 3.根据正确答案和用户作答信息进行判分
        Set<String> questionIdsAnswer = answersMap.keySet();
        // 存储当前考试每个题目的得分情况
        Map<String, Integer> judgeMap = new HashMap<>();
        // 考生作答地每个题目的选项(题目和题目之间用$分隔，题目有多个选项地话用-分隔,题目和选项之间用_分隔),用于查看考试详情
        // 例子：题目1的id_作答选项1-作答选项2&题目2的id_作答选项1&题目3_作答选项1-作答选项2-作答选项3
        StringBuilder answerOptionIdsSb = new StringBuilder();
        //  问题，正确答案，用户作答
        // 问题，正确答案
        List<Map<Map<String, String>, String>> ans_que = new ArrayList<>();
        // 用户此次考试的总分
        int totalScore = 0;
        double quesAllNum = 0;
        double rightAnsNum = 0;
        for (String questionId : questionIdsAnswer) {
            quesAllNum++;
            // 获取用户作答地这个题的答案信息
            Question question = questionMap.get(questionId);
            // 获取答案选项
            String questionAnswerOptionIds = replaceLastSeparator(question.getQuestionAnswerOptionIds());
            List<String> questionAnswerOptionIdList = Arrays.asList(questionAnswerOptionIds.split("-"));
            Collections.sort(questionAnswerOptionIdList);
            //todo：这里是答案的id
            // 如果是多选题的话，那么这里就是多个答案咯
            String answerStr = listConcat(questionAnswerOptionIdList);
            //通过答案id得到选项
            QueryWrapper<QuestionOption> qowrapper = new QueryWrapper<>();
            // 定义一个list集合去存所有的答案
            List<String> ansList = new ArrayList<>();

            // 查询每个答案，并添加到ansList中
            for (String answerId : questionAnswerOptionIdList) {
                qowrapper.lambda()
                        .select(QuestionOption::getQuestionOptionContent)
                        .eq(QuestionOption::getQuestionOptionId, answerId);
                QuestionOption qo = questionOptionMapper.selectOne(qowrapper);
                if (qo != null) {
                    ansList.add(qo.getQuestionOptionContent());
                }
            }
            // 将ansList拼接成带有编号的字符串
            StringBuilder answerStringBuilder = new StringBuilder();
            for (int i = 0; i < ansList.size(); i++) {
                answerStringBuilder.append("答案").append(i + 1).append(". ").append(ansList.get(i));
                if (i < ansList.size() - 1) {
                    answerStringBuilder.append("，"); // 每个答案之间加逗号分隔
                }
            }
            // 最终答案拼接结果
            String answerString = answerStringBuilder.toString();
            System.out.println("拼接后的答案字符串: " + answerString);
            //获取问题的名字
            String questionName = question.getQuestionName();
            // 获取用户作答
            List<String> questionUserOptionIdList = answersMap.get(questionId);
            Collections.sort(questionUserOptionIdList);
            //todo：这里是用户的答案id，需要改
            String userStr = listConcat(questionUserOptionIdList);
            // 定义一个list集合去存所有的答案
            List<String> queList = new ArrayList<>();

            // 查询每个答案，并添加到ansList中
            for (String quesId : questionUserOptionIdList) {
                qowrapper.lambda()
                        .select(QuestionOption::getQuestionOptionContent)
                        .eq(QuestionOption::getQuestionOptionId, quesId);
                QuestionOption qo = questionOptionMapper.selectOne(qowrapper);
                if (qo != null) {
                    queList.add(qo.getQuestionOptionContent());
                }
            }
            // 将ansList拼接成带有编号的字符串
            StringBuilder quesStringBuilder = new StringBuilder();
            for (int i = 0; i < queList.size(); i++) {
                quesStringBuilder.append("选项").append(i + 1).append(". ").append(ansList.get(i));
                if (i < queList.size() - 1) {
                    quesStringBuilder.append("，"); // 每个答案之间加逗号分隔
                }
            }
            //存着问题+正确答案
            Map<String, String> que_ans = new HashMap<>();
            que_ans.put(questionName, answerString);
            Map<Map<String, String>, String> que_ana_use = new HashMap<>();
            que_ana_use.put(que_ans, quesStringBuilder.toString());
            // 存着问题+正确答案+用户答案
            ans_que.add(que_ana_use);
            // 判断questionAnswerOptionIds和answersMap里面的答案是否相等
            //todo:所以这里我们有选项和答案可以进行分析,这里是answerStr和userStr
            if (answerStr.equals(userStr)) {
                rightAnsNum++;
                System.out.println("answerStr" + answerStr);
                System.out.println("userStr" + userStr);
                //所以这里先进行对答案进行分析
                // 说明题目作答正确,下面根据题型给分
                int score = 0;
                if (radioIdList.contains(questionId)) {
                    score = radioScore;
                }
                if (checkIdList.contains(questionId)) {
                    score = checkScore;
                }
                if (judgeIdList.contains(questionId)) {
                    score = judgeScore;
                }
                // 累计本次考试得分
                totalScore += score;
                // True代表题目答对
                answerOptionIdsSb.append(questionId + "@True_" + userStr + "$");
                judgeMap.put(questionId, score);
            } else {
                // 说明题目作答错误,直接判零分,False代表题目答错
                answerOptionIdsSb.append(questionId + "@False_" + userStr + "$");
                judgeMap.put(questionId, 0);
            }
        }
        int AllTotalScore=exam.getExamScore();
        System.out.printf("正确率 %.2f%%\n", (double) totalScore / AllTotalScore * 100);        //3.3 传过去题目+用户答案+正确答案便于分析
        System.out.println("问题+答案" + ans_que.toString());
        // 4.todo：计算得分，记录本次考试结果，存到ExamRecord中
        ExamRecord examRecord = new ExamRecord();
        examRecord.setExamRecordId(IdUtil.simpleUUID());
        examRecord.setExamId(examId);
        String ansQueJson = objectMapper.writeValueAsString(ans_que);
        examRecord.setAnaQue(ansQueJson);
        // 注意去掉最后可能有的&_-
        examRecord.setAnswerOptionIds(replaceLastSeparator(answerOptionIdsSb.toString()));
        examRecord.setExamJoinerId(userId);
        examRecord.setExamJoinDate(new Date());
        examRecord.setExamJoinScore(totalScore);
        examRecord.setExamType(exam.getExamType());
        examRecordMapper.insert(examRecord);
        // 获取插入记录的主键 ID
        String examRecordId = examRecord.getExamRecordId();
        ExamRecordAnalysisVo examRecordAnalysisVo = new ExamRecordAnalysisVo();
        BeanUtils.copyProperties(examRecord, examRecordAnalysisVo);
        ExamAnalysis examAnalysis = analysisAnsQue(ans_que, examId, (double) totalScore / AllTotalScore, totalScore,true,examRecordId);
        examRecordAnalysisVo.setExamAnalysis(examAnalysis);
        return examRecordAnalysisVo;
    }

    //这个方法是去分析用户的答案
    public ExamAnalysis analysisAnsQue(List<Map<Map<String, String>, String>> list, String examId, double rate, int totalScore,boolean flag, String examRecordId) {
        //这里对用户进行分析咯
        //1. 首先让她对用户的答题情况进行分析（比如正确率、等等）
        //2. 对不同知识点的掌握情况进行分析
        //3. 给出合理的建议和提醒
        //4. 推出计划？

        //todo:这里有待改进，分析情况整理
        String userId = WisUserIdContext.getUserIdContext();
        // 1. 查询并转为JSON字符串
        QueryWrapper<ExamAnalysis> wrapper = new QueryWrapper<>();
        wrapper.lambda()
                .eq(ExamAnalysis::getExamId, examId)
                .eq(ExamAnalysis::getUserId, userId)
                .select(ExamAnalysis::getPerformanceSummary)
                .orderByDesc(ExamAnalysis::getCreateTime) // 按创建时间降序，获取最新的记录
                .last("LIMIT 30"); // 限制最多返回30条数据

// 获取之前做过该试卷的历史评价列表
        List<String> listHistoryPerformanceSummary = examAnalysisMapper.selectObjs(wrapper)
                .stream()
                .filter(Objects::nonNull) // 过滤掉空值，避免出现null
                .map(Object::toString)
                .toList();

// 继续后续的逻辑...


        // 检查历史评价是否为空，若为空则给出默认提示
        if (listHistoryPerformanceSummary.isEmpty()) {
            listHistoryPerformanceSummary = List.of("暂无历史评价");
        }
        System.out.println("历史评价" + listHistoryPerformanceSummary);
        // 2. 查询最大 attemptNumber，并处理null情况
        wrapper.lambda()
                .select(ExamAnalysis::getAttemptNumber)
                .eq(ExamAnalysis::getExamId, examId)
                .eq(ExamAnalysis::getUserId, userId)
                .orderByDesc(ExamAnalysis::getAttemptNumber)
                .last("LIMIT 1");

        ExamAnalysis examAnalysisAttemptNumber = examAnalysisMapper.selectOne(wrapper);
        Integer attemptNumber = (examAnalysisAttemptNumber != null && examAnalysisAttemptNumber.getAttemptNumber() != null)
                ? examAnalysisAttemptNumber.getAttemptNumber()
                : 0; // 如果为空，则设置为0
        System.out.println("答题次数" + attemptNumber);
        // 3. 转换题目和历史评价为JSON字符串，并捕获异常
        String userMessage;
        //存放着该学生的答题情况
        String questionsJson = null;
        try {
            userMessage = convertListToJson(list, listHistoryPerformanceSummary);

            // 将 JSON 字符串解析为 JsonNode
            JsonNode rootNode = objectMapper.readTree(userMessage);

            // 提取 questions 节点
            JsonNode questionsNode = rootNode.path("questions");

            // 将 questions 节点转换为 JSON 字符串
            questionsJson = objectMapper.writeValueAsString(questionsNode);
            // 得到了该
        } catch (Exception e) {
            e.printStackTrace();
            System.out.println("Error in converting list to JSON format.");
            userMessage = "{}"; // 设置默认值为空的JSON字符串，避免空值传递
        }
        String analysis2 = aiManager.doSyncStableRequest(GENERATE_SCORING_SYSTEM_MESSAGE, userMessage);
        // todo：截取需要的 JSON 信息
        int start = analysis2.indexOf("{");
        int end = analysis2.lastIndexOf("}");
        String analysis = analysis2.substring(start, end + 1);
        System.out.println("analysis" + analysis);
        System.out.println("ai返回的json" + analysis2);
        try {
            JsonNode root = objectMapper.readTree(analysis);
            String resultKnowledge = root.path("resultKnowledge").asText();
            String resultDesc = root.path("resultDesc").asText();
            if (resultKnowledge.startsWith("知识点掌握情况")) {
                resultKnowledge = resultKnowledge.substring("知识点掌握情况".length());
            }
            List<String> suggestedReviewTopicsList = new ArrayList<>();
            root.path("suggestedReviewTopics").forEach(node -> suggestedReviewTopicsList.add(node.asText()));
            String suggestedReviewTopics = String.join(", ", suggestedReviewTopicsList);
            String performanceSummary = root.path("performanceSummary").asText();
            if (resultKnowledge.startsWith("评价总结")) {
                resultKnowledge = resultKnowledge.substring("评价总结".length());
            }
            List<String> weakPointsList = new ArrayList<>();
            root.path("weakPoints").forEach(node -> weakPointsList.add(node.asText()));
            String weakPoints = String.join(", ", weakPointsList);
            //获得考试名称
            QueryWrapper<Exam> getNameExam = new QueryWrapper<>();
            getNameExam.lambda()
                    .eq(Exam::getExamId, examId)
                    .select(Exam::getExamName);
            Exam examName2 = examMapper.selectOne(getNameExam);
            String examName = examName2.getExamName();
            // 构建 ExamAnalysis 对象
            ExamAnalysis examAnalysis = new ExamAnalysis();
            examAnalysis.setUserId(userId);
            examAnalysis.setExamId(examId);
            examAnalysis.setExamName(examName);
            examAnalysis.setKnowledgeMastery(resultKnowledge);
            //如果是true的话就代表着是做题来的，做题次数需要加1，但是
            if(flag){
                examAnalysis.setAttemptNumber(attemptNumber + 1);
            }else {
                examAnalysis.setAttemptNumber(attemptNumber);
            }
            examAnalysis.setPerformanceSummary(performanceSummary);
            examAnalysis.setResultDesc(resultDesc);
            examAnalysis.setSuggestedReviewTopics(suggestedReviewTopics);
            System.out.println("正确率rate" + rate);
            examAnalysis.setCorrectRate(BigDecimal.valueOf(rate));
            examAnalysis.setExamScore(totalScore);
            examAnalysis.setWeakPoints(weakPoints);
            examAnalysis.setQueCorrectUserAns(questionsJson);
            System.out.println("examAnalysis ai分析" + examAnalysis.toString());
            // todo： 这里可以返回给前端分析结果，这个格式可以鉴定一下，现在做题后返回后那边要加个页面，进行这个的展示，还有是否选择生成题库的展示。
            // 插入新评价记录
            QueryWrapper<Exam> wrapperExam = new QueryWrapper<>();
            wrapperExam.lambda()
                    .eq(Exam::getExamId, examId)
                    .select(Exam::getExamType);
            Exam exam = examMapper.selectOne(wrapperExam);
            String examType = exam.getExamType();
            examAnalysis.setExamType(examType);
            examAnalysis.setCorrectRate(BigDecimal.valueOf(rate*100));
            if(!examRecordId.equals("-1")){
                // 使用 LambdaUpdateWrapper 构建更新条件
                LambdaUpdateWrapper<ExamRecord> updateWrapper = new LambdaUpdateWrapper<>();
                updateWrapper
                        .eq(ExamRecord::getExamRecordId, examRecordId) // 条件：examRecordId 匹配
                        .set(ExamRecord::getQueCorrectUserAns, questionsJson); // 更新字段：queCorrectUserAns

                // 执行更新操作
                examRecordMapper.update(updateWrapper);
            }
            examAnalysisMapper.insert(examAnalysis);
            return examAnalysis;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;

    }

    public void generateQue(List<Map<Map<String, String>, String>> map) {
        //1. 这里是去生成对应的问题+试卷咯【去看问题和试卷是怎么弄的，即如何创建试卷的-->创建问题等等】
        //2， 然后这里创建完要加入到用户计划里面去
    }

    //todo:将list转为json串，方便ai识别
    private static final ObjectMapper objectMapper = new ObjectMapper();


    public static String convertListToJson(List<Map<Map<String, String>, String>> questionList, List<String> historySummary) {
        // 构建最终的结构，用于JSON格式
        Map<String, Object> result = new HashMap<>();
        // 解析并构建题目列表格式 [{ "question": "题目描述", "correctAnswer": "正确答案", "userAnswer": "用户答案" }]
        List<Map<String, String>> formattedQuestionList = questionList.stream().map(entry -> {
            Map.Entry<Map<String, String>, String> questionAndAnswerEntry = entry.entrySet().iterator().next();
            Map<String, String> questionAndAnswer = questionAndAnswerEntry.getKey();
            String userAnswer = questionAndAnswerEntry.getValue();

            // 构造符合AI提示词的格式
            Map<String, String> formattedQuestion = new HashMap<>();
            formattedQuestion.put("question", questionAndAnswer.keySet().iterator().next());
            formattedQuestion.put("correctAnswer", questionAndAnswer.values().iterator().next());
            formattedQuestion.put("userAnswer", userAnswer);

            return formattedQuestion;
        }).toList();
        // 将题目列表和历史评价列表添加到最终结果中
        result.put("questions", formattedQuestionList);
        result.put("historySummary", historySummary);
        try {
            // 转换为JSON字符串
            return objectMapper.writeValueAsString(result);
        } catch (Exception e) {
            e.printStackTrace();
            return "";
        }
    }

    @Override
    public List<ExamRecordVo> getExamRecordList(String userId, String type) {
        // 获取指定用户下的考试记录列表
        QueryWrapper<ExamRecord> wrapper = new QueryWrapper<>();
        if ("null".equals(type)) {
            wrapper.lambda()
                    .eq(ExamRecord::getExamJoinerId, userId)
                    .orderByDesc(ExamRecord::getExamJoinDate);
        } else {
            wrapper.lambda()
                    .eq(ExamRecord::getExamJoinerId, userId)
                    .eq(ExamRecord::getExamType, type)
                    .orderByDesc(ExamRecord::getExamJoinDate);
        }

        // 查询所有记录
        List<ExamRecord> examRecordList = examRecordMapper.selectList(wrapper);

        // 按 examId 分组，仅保留 exam_join_date 最新的记录
        Map<String, ExamRecord> latestExamRecordMap = new HashMap<>();
        for (ExamRecord record : examRecordList) {
            String examId = record.getExamId();
            if (!latestExamRecordMap.containsKey(examId) ||
                    record.getExamJoinDate().after(latestExamRecordMap.get(examId).getExamJoinDate())) {
                latestExamRecordMap.put(examId, record);
            }
        }

        // 将最新记录转为列表
        List<ExamRecord> latestExamRecordList = new ArrayList<>(latestExamRecordMap.values());

        // 构建返回的 VO 对象列表
        List<ExamRecordVo> examRecordVoList = new ArrayList<>();
        for (ExamRecord examRecord : latestExamRecordList) {
            ExamRecordVo examRecordVo = new ExamRecordVo();
            Exam exam = examMapper.selectById(examRecord.getExamId());
            examRecordVo.setExam(exam);
            WisUser wisUser = wisuserMapper.selectById(userId);
            examRecordVo.setWisUser(wisUser);
            examRecordVo.setExamRecord(examRecord);
            examRecordVoList.add(examRecordVo);
        }

        return examRecordVoList;
    }


    @Override
    public RecordDetailVo getRecordDetail(String recordId) {
        // 获取考试详情的封装对象
        ExamRecord record = examRecordMapper.selectById(recordId);
        RecordDetailVo recordDetailVo = new RecordDetailVo();
        recordDetailVo.setExamRecord(record);
        // 用户的答案，需要解析
        HashMap<String, List<String>> answersMap = new HashMap<>();
        HashMap<String, String> resultsMap = new HashMap<>();
        assert record != null;
        String answersStr = record.getAnswerOptionIds();
        // $分隔题目,因为$在正则中有特殊用途(行尾)，所以需要括起来
        String[] questionArr = answersStr.split("[$]");
        for (String questionStr : questionArr) {
            System.out.println(questionStr);
            // 区分开题目标题和选项
            String[] questionTitleResultAndOption = questionStr.split("_");
            String[] questionTitleAndResult = questionTitleResultAndOption[0].split("@");
            String[] questionOptions = questionTitleResultAndOption[1].split("-");
            // 题目：答案选项
            answersMap.put(questionTitleAndResult[0], Arrays.asList(questionOptions));
            // 题目：True / False
            resultsMap.put(questionTitleAndResult[0], questionTitleAndResult[1]);
        }
        recordDetailVo.setAnswersMap(answersMap);
        recordDetailVo.setResultsMap(resultsMap);
        // 下面再计算正确答案的map
        ExamDetailVo examDetailVo = getExamDetail(record.getExamId());
        List<String> questionIdList = new ArrayList<>();
        questionIdList.addAll(Arrays.asList(examDetailVo.getRadioIds()));
        questionIdList.addAll(Arrays.asList(examDetailVo.getCheckIds()));
        questionIdList.addAll(Arrays.asList(examDetailVo.getJudgeIds()));
        // 获取所有的问题对象
        List<Question> questionList = questionMapper.selectBatchIds(questionIdList);
        HashMap<String, List<String>> answersRightMap = new HashMap<>();
        for (Question question : questionList) {
            // 记得去掉最后可能出现的特殊字符
            String questionAnswerOptionIdsStr = replaceLastSeparator(question.getQuestionAnswerOptionIds());
            String[] questionAnswerOptionIds = questionAnswerOptionIdsStr.split("-");
            answersRightMap.put(question.getQuestionId(), Arrays.asList(questionAnswerOptionIds));
        }
        recordDetailVo.setAnswersRightMap(answersRightMap);
        return recordDetailVo;
    }

    @Override
    public List<String> getExamTypes() {
        QueryWrapper<Exam> wrapper = new QueryWrapper<>();
        wrapper.lambda()
                .select(Exam::getExamType);
        List<Object> type = examMapper.selectObjs(wrapper);
        // 去重
        List<String> uniqueTypes = type.stream()
                .filter(Objects::nonNull) // 过滤掉null值
                .map(Object::toString) // 将Object转换为String
                .distinct() // 去重
                .collect(Collectors.toList()); // 收集结果到列表
        return uniqueTypes;
    }

    @Override
    public List<ExamVo> getTypeToExam(String type,Boolean ifAi) {
        QueryWrapper<Exam> wrapper = new QueryWrapper<>();
        if(type.equals("true")){
            ifAi=true;
        }
        System.out.println(ifAi.equals(true));
        //得到ai分析的，没有分类
        if(ifAi.equals(true)){
            wrapper.lambda()
                    //这里的话默认是false，然后如果传true的话就是得到ai题库了
                    .eq(Exam::getExamIfAi,ifAi);
        }//得到
        else if(!type.equals("null")){
            wrapper.lambda()
                    //这里的话默认是false，然后如果传true的话就是得到ai题库了
                    .eq(Exam::getExamType,type);
        }

        List<Exam> exams = examMapper.selectList(wrapper);
        //讲exam疯转成vo
        return getExamVos(exams);
    }
    //这里的话前面去展示就是有分类的，所以这里的试卷其实就是同一个分类了。
    public Exam generateExam(List<String> examIdsList) throws JsonProcessingException {
        String userId = WisUserIdContext.getUserIdContext();

        // 这里根据examId的情况去生成题目
        String examType = null;
        List<Map<String,Object>> subQueAnUser = new ArrayList<>();

        // 遍历所有 examId 生成相关的考试信息
        for (String examId : examIdsList) {
            // 使用 QueryWrapper 构造查询条件
            QueryWrapper<ExamRecord> wrapper = new QueryWrapper<>();
            wrapper.lambda()
                    .eq(ExamRecord::getExamId, examId)
                    .eq(ExamRecord::getExamJoinerId, userId)
                    .orderByDesc(ExamRecord::getCreatTime)
                    .last("LIMIT 1");

            // 查询 examRecord 对象
            ExamRecord examRecord = examRecordMapper.selectOne(wrapper);

            // 如果 examRecord 为 null，则跳过当前 examId 或处理异常情况
            if (examRecord == null) {
                // 可以选择继续执行、记录日志或抛出异常，下面以跳过为例
                continue;
            }

            // 获取用户的答题信息，如果为 null，需要进行处理
            String queCorrectUserAns = examRecord.getQueCorrectUserAns();
            String type = examRecord.getExamType();

            // 如果答题信息为空，或者类型为空，进行处理
            if (queCorrectUserAns == null) {
                queCorrectUserAns = "未答题";  // 这里可以根据需求选择默认值
            }
            if (type == null) {
                type = "未知类型";  // 如果考试类型为空，默认使用"未知类型"
            }

            // 设置 examType（可以选择是否需要合并所有考试类型，或者只设置最后一个）
            examType = type;

            // 将数据放入 map 中
            Map<String, Object> map = new HashMap<>();
            map.put("subject", type);
            map.put("questions", queCorrectUserAns);

            // 添加到 subQueAnUser 列表
            subQueAnUser.add(map);
        }
        System.out.println(subQueAnUser);
        String jsonSubQue = objectMapper.writeValueAsString(subQueAnUser);
        // 现在的话，应该是先让ai生成问题，然后再去存入ai，然后去调用创建试卷的逻辑即可。
        //然后这里交给ai分析，得到对应的问题

        // 请求单选题生成
        String GENERATE_SINGLE_CHOICE_QUESTION_REQUEST = GENERATE_QUESTION_SYSTEM_MESSAGE_Single + "请为用户生成单选题，题量不少于3道。";

        // 请求多选题生成
        String GENERATE_MULTI_CHOICE_QUESTION_REQUEST = GENERATE_QUESTION_SYSTEM_MESSAGE_Multiple + "请为用户生成多选题，题量不少于3道。";

        // 请求判断题生成
        String GENERATE_JUDGE_QUESTION_REQUEST = GENERATE_QUESTION_SYSTEM_MESSAGE_JUDGE + "请为用户生成判断题，题量不少于3道。";
        String  singleQuestion = aiManager.doSyncStableRequest(GENERATE_SINGLE_CHOICE_QUESTION_REQUEST, jsonSubQue);
        // 1. 提取 AI 返回的 JSON 部分
        String jsonSingleContent = extractJsonContent(singleQuestion);
        System.out.println();
        // 2. 使用 ObjectMapper 将提取的 JSON 字符串解析为 List<QuestionCreateVo>
        ObjectMapper objectMapper = new ObjectMapper();
        // 接收返回的格式·
        List<QuestionCreateVo> questionSingleList = objectMapper.readValue(jsonSingleContent,
                objectMapper.getTypeFactory().constructCollectionType(List.class, QuestionCreateVo.class));
        List<String> nameList=new ArrayList<>();
        List<ExamQuestionSelectVo> singleList=new ArrayList<>();
        for (QuestionCreateVo questionCreateVo : questionSingleList) {
            questionCreateVo.setQuestionCreatorId(userId);
            String questionId = questionCreate(questionCreateVo);
            ExamQuestionSelectVo examQuestionSelectVo=new ExamQuestionSelectVo();
            examQuestionSelectVo.setChecked(true);
            examQuestionSelectVo.setQuestionId(questionId);
            examQuestionSelectVo.setQuestionName(questionCreateVo.getQuestionName());
            nameList.add(questionCreateVo.getQuestionName());
            singleList.add(examQuestionSelectVo);
        }
        String  multiQuestion = aiManager.doSyncStableRequest(GENERATE_MULTI_CHOICE_QUESTION_REQUEST, jsonSubQue);
        String jsonMultiContent = extractJsonContent(multiQuestion);
        List<QuestionCreateVo> questionMultiList = objectMapper.readValue(jsonMultiContent,
                objectMapper.getTypeFactory().constructCollectionType(List.class, QuestionCreateVo.class));
        List<ExamQuestionSelectVo> mutliList=new ArrayList<>();
        for (QuestionCreateVo questionCreateVo : questionMultiList) {
            questionCreateVo.setQuestionCreatorId(userId);
            String questionId = questionCreate(questionCreateVo);
            ExamQuestionSelectVo examQuestionSelectVo=new ExamQuestionSelectVo();
            examQuestionSelectVo.setChecked(true);
            examQuestionSelectVo.setQuestionId(questionId);
            examQuestionSelectVo.setQuestionName(questionCreateVo.getQuestionName());
            nameList.add(questionCreateVo.getQuestionName());
            mutliList.add(examQuestionSelectVo);
        }
        String  judgeQuestion = aiManager.doSyncStableRequest(GENERATE_JUDGE_QUESTION_REQUEST, jsonSubQue);
        String jsonJudgeContent = extractJsonContent(judgeQuestion);
        List<QuestionCreateVo> questionJudgeList = objectMapper.readValue(jsonJudgeContent,
                objectMapper.getTypeFactory().constructCollectionType(List.class, QuestionCreateVo.class));
        List<ExamQuestionSelectVo> JudgeList=new ArrayList<>();
        for (QuestionCreateVo questionCreateVo : questionJudgeList) {
            questionCreateVo.setQuestionCreatorId(userId);
            String questionId = questionCreate(questionCreateVo);
            ExamQuestionSelectVo examQuestionSelectVo=new ExamQuestionSelectVo();
            examQuestionSelectVo.setChecked(true);
            examQuestionSelectVo.setQuestionId(questionId);
            examQuestionSelectVo.setQuestionName(questionCreateVo.getQuestionName());
            nameList.add(questionCreateVo.getQuestionName());
            JudgeList.add(examQuestionSelectVo);
        }
        String jsonNameList = objectMapper.writeValueAsString(nameList);

        String aiExam = aiManager.doSyncStableRequest(GENERATE_EXAM_NAME_SYSTEM_MESSAGE, jsonNameList);
        String jsonName = extractJsonContentExamName(aiExam);
        System.out.println(jsonName);
        // 解析 JSON 内容并提取试卷名称
        JsonNode rootNode = objectMapper.readTree(jsonName);
        String examName = rootNode.path("examName").asText();
        String examDescription = rootNode.path("examDescription").asText();
        System.out.println(examName);
        ExamCreateVo examCreateVo=new ExamCreateVo();
        examCreateVo.setExamName(examName);
        //多选题
        examCreateVo.setChecks(mutliList);
        examCreateVo.setJudges(JudgeList);
        //单选题
        examCreateVo.setRadios(singleList);
        examCreateVo.setExamScoreRadio(3);
        examCreateVo.setExamScoreCheck(5);
        examCreateVo.setExamScoreJudge(3);
        examCreateVo.setExamAvatar("https://on-wisdomcloud.oss-cn-shenzhen.aliyuncs.com/exam/cover/44b08c29-ab66-4821-a6a8-210f36885241.png");
        examCreateVo.setExamTimeLimit(30);
        examCreateVo.setExamType(examType);

        examCreateVo.setExamDescription(examDescription);
        examCreateVo.setExamIfAi(true);
        System.out.println("ifaivo"+examCreateVo.getExamIfAi());
        //这里的话就是去创建试卷了，会插入数据库中，前端再去获取列表即可
        Exam exam = create(examCreateVo, userId);
        return exam;
    }
    public static String extractJsonContent(String response) {
        int startIndex = response.indexOf("[");
        int endIndex = response.lastIndexOf("]") + 1;

        if (startIndex != -1 && endIndex != -1 && startIndex < endIndex) {
            return response.substring(startIndex, endIndex);
        } else {
            throw new IllegalArgumentException("无法找到有效的 JSON 部分");
        }
    }
    public static String extractJsonContentExamName(String response) {
        int startIndex = response.indexOf("{");
        int endIndex = response.lastIndexOf("}") + 1;

        if (startIndex != -1 && endIndex != -1 && startIndex < endIndex) {
            return response.substring(startIndex, endIndex);
        } else {
            throw new IllegalArgumentException("无法找到有效的 JSON 部分");
        }
    }
    private String listConcat(List<String> strList) {
        StringBuilder sb = new StringBuilder();
        for (String str : strList) {
            sb.append(str);
            sb.append("-");
        }
        return replaceLastSeparator(sb.toString());
    }

    // 根据传来的exam进行封装成examvo，即多了radios等等
    private List<ExamVo> getExamVos(List<Exam> examList) {
        // 需要自定义的exam列表
        List<ExamVo> examVoList = new ArrayList<>();
        // 循环完成每个属性的定制
        for (Exam exam : examList) {
            ExamVo examVo = new ExamVo();
            // 先尽量复制能复制的所有属性
            BeanUtils.copyProperties(exam, examVo);
            // 设置问题的创建者
            examVo.setExamCreator(
                    Objects.requireNonNull(
                            wisuserMapper.selectById(
                                    exam.getExamCreatorId()
                            )
                    ).getUserUsername()
            );

            // 获取所有单选题列表，并赋值到ExamVo的属性ExamQuestionSelectVoRadioList上
            List<ExamQuestionSelectVo> radioQuestionVoList = new ArrayList<>();
            List<Question> radioQuestionList = questionMapper.selectBatchIds(
                    Arrays.asList(exam.getExamQuestionIdsRadio().split("-"))
            );
            for (Question question : radioQuestionList) {
                ExamQuestionSelectVo radioQuestionVo = new ExamQuestionSelectVo();
                BeanUtils.copyProperties(question, radioQuestionVo);
                radioQuestionVo.setChecked(true); // 考试中的问题肯定被选中的
                radioQuestionVoList.add(radioQuestionVo);
            }
            examVo.setExamQuestionSelectVoRadioList(radioQuestionVoList);

            // 获取所有多选题列表，并赋值到ExamVo的属性ExamQuestionSelectVoCheckList上
            List<ExamQuestionSelectVo> checkQuestionVoList = new ArrayList<>();
            List<Question> checkQuestionList = questionMapper.selectBatchIds(
                    Arrays.asList(exam.getExamQuestionIdsCheck().split("-"))
            );
            for (Question question : checkQuestionList) {
                ExamQuestionSelectVo checkQuestionVo = new ExamQuestionSelectVo();
                BeanUtils.copyProperties(question, checkQuestionVo);
                checkQuestionVo.setChecked(true); // 考试中的问题肯定被选中的
                checkQuestionVoList.add(checkQuestionVo);
            }
            examVo.setExamQuestionSelectVoCheckList(checkQuestionVoList);

            // 获取所有多选题列表，并赋值到ExamVo的属性ExamQuestionSelectVoJudgeList上
            List<ExamQuestionSelectVo> judgeQuestionVoList = new ArrayList<>();
            List<Question> judgeQuestionList = questionMapper.selectBatchIds(
                    Arrays.asList(exam.getExamQuestionIdsJudge().split("-"))
            );
            for (Question question : judgeQuestionList) {
                ExamQuestionSelectVo judgeQuestionVo = new ExamQuestionSelectVo();
                BeanUtils.copyProperties(question, judgeQuestionVo);
                judgeQuestionVo.setChecked(true); // 考试中的问题肯定被选中的
                judgeQuestionVoList.add(judgeQuestionVo);
            }
            examVo.setExamQuestionSelectVoJudgeList(judgeQuestionVoList);

            // 把examVo加到examVoList中
            examVoList.add(examVo);
        }
        return examVoList;
    }

    /**
     * 把字符串最后一个字符-替换掉
     *
     * @param str 原始字符串
     * @return 替换掉最后一个-的字符串
     */
    private String replaceLastSeparator(String str) {
        String lastChar = str.substring(str.length() - 1);
        // 题目和题目之间用$分隔，题目有多个选项地话用-分隔,题目和选项之间用_分隔
        if ("-".equals(lastChar) || "_".equals(lastChar) || "$".equals(lastChar)) {
            str = StrUtil.sub(str, 0, str.length() - 1);
        }
        return str;
    }

    /**
     * 去除字符串最后的，防止split的时候出错
     *
     * @param str 原始字符串
     * @return
     */
    public static String trimMiddleLine(String str) {
        if (str.charAt(str.length() - 1) == '-') {
            str = str.substring(0, str.length() - 1);
        }
        return str;
    }

}
